#include <string.h>
#include <stdio.h>
#include "mhscpu.h"

#define  MAIN_LIST		0
#define  UART0_LIST		1
#define  UART1_LIST		2

void UART_Configuration(void);
void UART0_RemapTest(void);
void UART1_RemapTest(void);

uint8_t GetCmd(void);
void printTestList(uint32_t list);
int main(void)
{
	uint8_t tmp;
	
	SYSCTRL_APBPeriphClockCmd(SYSCTRL_APBPeriph_UART0 | SYSCTRL_APBPeriph_UART1 | SYSCTRL_APBPeriph_GPIO,ENABLE);
	SYSCTRL_APBPeriphResetCmd(SYSCTRL_APBPeriph_UART0 | SYSCTRL_APBPeriph_UART1, ENABLE);
	
	GPIO_PinRemapConfig(GPIOA, GPIO_Pin_0 | GPIO_Pin_1, GPIO_Remap_0);
	UART_Configuration();
	
	printf("MegaHunt SCPU UART Demo V1.0.\n");

	printTestList(MAIN_LIST);

	if(UART_GetLineStatus(UART0) & UART_LINE_STATUS_RX_RECVD)
	{
		tmp = UART_ReceiveData(UART0);
		UART_SendData(UART0, tmp);
	}

	while(1) {
		
		tmp = GetCmd();
		if (tmp)
		{
			switch (tmp)
			{
			case '0':
				{
					UART0_RemapTest();
					break;
				}
			case '1':
				{
					UART1_RemapTest();
					break;
				}

			case 'p':
			case 'P':
				{
					printTestList(MAIN_LIST);
				}
			}
		}
		
	}
}

void UART1_RemapTest(void)
{
	uint8_t tmp = 0;

	printTestList(UART1_LIST);

	printf("0:UART1 Remap Default\n");
	printf("1:UART1 Remap PB12 PB13\n");
	printf("2:UART1 Remap PC0 PC1\n");
	while(1)
	{
		if (0 != (tmp = GetCmd()))
		{
			switch (tmp)
			{
			case '0':
				{
					printf("UART1 Remap to Default\n");
					GPIO_PinRemapConfig(GPIOD, GPIO_Pin_4 | GPIO_Pin_5, GPIO_Remap_0);
					break;
				}
			case '1':
				{
					printf("UART1 Remap to PB12 PB13\n");
					GPIO_PinRemapConfig(GPIOD, GPIO_Pin_4 | GPIO_Pin_5, GPIO_Remap_0);
					GPIO_PinRemapConfig(GPIOC, GPIO_Pin_0 | GPIO_Pin_1, GPIO_Remap_0);
					GPIO_PinRemapConfig(GPIOB, GPIO_Pin_12 | GPIO_Pin_13, GPIO_Remap_3);
					break;
				}
			case '2':
				{
					printf("UART1 Remap to PC0 PC1\n");
					GPIO_PinRemapConfig(GPIOD, GPIO_Pin_4 | GPIO_Pin_5, GPIO_Remap_0);
					GPIO_PinRemapConfig(GPIOB, GPIO_Pin_12 | GPIO_Pin_13, GPIO_Remap_0);
					GPIO_PinRemapConfig(GPIOC, GPIO_Pin_0 | GPIO_Pin_1, GPIO_Remap_3);
					break;
				}
			case 'p':
			case 'P':
				{
					printTestList(UART1_LIST);
					break;
				}
			case 0x08:
				{
					printTestList(MAIN_LIST);
					return;
				}
			}
		}
	}
}


void UART0_RemapTest(void)
{
	uint8_t tmp = 0;

	printTestList(UART0_LIST);

	printf("0:UART0 Remap Default\n");
	printf("1:UART0 Remap PA14 PA15\n");
	while(1)
	{
		if (0 != (tmp = GetCmd()))
		{
			switch (tmp)
			{
			case '0':
				{
					printf("UART0 Remap to Default\n");
					GPIO_PinRemapConfig(GPIOA, GPIO_Pin_0 | GPIO_Pin_1, GPIO_Remap_0);
					break;
				}
			case '1':
				{
					printf("UART0 Remap to PA14 PA15\n");
					GPIO_PinRemapConfig(GPIOA, GPIO_Pin_8 | GPIO_Pin_9, GPIO_Remap_1);
					GPIO_PinRemapConfig(GPIOA, GPIO_Pin_14 | GPIO_Pin_15, GPIO_Remap_3);
					break;
				}
			
			case 'p':
			case 'P':
				{
					printTestList(UART0_LIST);
					break;
				}
			case 0x08:
				{
					printTestList(MAIN_LIST);
					return;
				}
			}
		}
	}
}

uint8_t GetCmd(void)
{
	uint8_t tmp = 0;
	
	if(UART_GetLineStatus(UART0) & UART_LINE_STATUS_RX_RECVD)
	{
		tmp = UART_ReceiveData(UART0);
	}
	else if(UART_GetLineStatus(UART1) & UART_LINE_STATUS_RX_RECVD)
	{
		tmp = UART_ReceiveData(UART1);
// 		UART_SendData(UART1, tmp);
	}

	if(tmp)
	{
		printf("cmd is %c\n", tmp);
	}
	
	return tmp;
}

void printTestList(uint32_t list)
{
	switch (list)
	{
	case MAIN_LIST:
		printf("===================UART Remap Test================\n");
		printf("0:UART0 Remap Test\n");
		printf("1:UART1 Remap Test\n");
		printf("p:Show List\n");
		printf("=======================List End===================\n");
		break;
	case UART0_LIST:
		printf("==================UART0 Remap Test================\n");
		printf("0:UART0 Remap Default\n");
		printf("1:UART0 Remap PA14 PA15\n");
		printf("p:Show List\n");
		printf("backSpace:return MainList\n");
		printf("=======================List End===================\n");
		break;
	case UART1_LIST:
		printf("==================UART1 Remap Test================\n");
		printf("0:UART1 Remap Default\n");
		printf("1:UART1 Remap PB12 PB13\n");
		printf("2:UART1 Remap PC0 PC1\n");
		printf("p:Show List\n");
		printf("backSpace:return MainList\n");
		printf("=======================List End===================\n");
		break;
	}
}

void UART_Configuration(void)
{
	UART_InitTypeDef UART_InitStructure;
	
	UART_InitStructure.UART_BaudRate = 115200;
	UART_InitStructure.UART_WordLength = UART_WordLength_8b;
	UART_InitStructure.UART_StopBits = UART_StopBits_1;
	UART_InitStructure.UART_Parity = UART_Parity_No;

	UART_Init(UART0, &UART_InitStructure);
	UART_Init(UART1, &UART_InitStructure);
}


int SER_PutChar (int ch) {

	while(!UART_IsTXEmpty(UART0));
	UART_SendData(UART0, (uint8_t) ch);
	while(!UART_IsTXEmpty(UART1));
	UART_SendData(UART1, (uint8_t) ch);
	return ch;
}

int fputc(int c, FILE *f)
{
	/* Place your implementation of fputc here */
	/* e.g. write a character to the USART */
	if (c == '\n')  {
		SER_PutChar('\r');
	}
	return (SER_PutChar(c));
}


#ifdef  USE_FULL_ASSERT

/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t* file, uint32_t line)
{ 
	/* User can add his own implementation to report the file name and line number,
	 ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */

	/* Infinite loop */
	while (1)
	{
	}
}
#endif
